﻿using MathNet.Numerics.Distributions;
using Microsoft.AspNetCore.Mvc;
using ztDataNet.Db;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using SqlSugar;
using StackExchange.Redis;


namespace ztDataNet.Controllers
{
    /// <summary>
    /// 公共类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [Route("api/[controller]")]
    [ApiController]
    
    public class BaseController<T> : ControllerBase where T : class, IEntity, new()
    {
        private readonly ISqlSugarClient db;
       
        private readonly IDistributedCache cache;

        private readonly string RedisConnection = "119.45.240.39:6379,password=04985807";

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="db"></param>
        /// <param name="cache"></param>
        public BaseController(ISqlSugarClient db, IDistributedCache cache)
        {
            this.db = db;
        
            this.cache = cache;
        }
        
        /// <summary>
        /// 插入单条
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        // POST: api/Entity/Add
        [HttpPost("Add")]
        public async Task<IActionResult> AddEntity([FromBody] T entity)
        {
            var id = db.Insertable(entity).ExecuteReturnIdentity();

            //if (id > 0)
            //{

            //    var cacheKey = $"{typeof(T).Name}-{entity.id}";

            //    // 将数据序列化为JSON
            //    var serializedEntity = JsonConvert.SerializeObject(entity);

            //    // 将数据存储到缓存中，设置滑动过期时间为5分钟
            //    var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
            //    await cache.SetStringAsync(cacheKey, serializedEntity, cacheEntryOptions);

            //    var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
            //    var server = _connection.GetServer(_connection.GetEndPoints().First());
            //    var keys = server.Keys(pattern: "*");
            //    var db = _connection.GetDatabase();

            //    foreach (var key in keys)
            //    {
            //        if (key.ToString().StartsWith("ztDataNet:All"+typeof(T).Name))
            //        {
            //            await db.KeyDeleteAsync(key);
            //        }
            //    }

            //}

            return Ok(id);
        }
        [HttpPost("Addrid")]
        public async Task<IActionResult> AddridEntity([FromBody] T entity)
        {
            var id = db.Insertable(entity).ExecuteReturnIdentity();

            //if (id > 0)
            //{

            //    var cacheKey = $"{typeof(T).Name}-{entity.id}";

            //    // 将数据序列化为JSON
            //    var serializedEntity = JsonConvert.SerializeObject(entity);

            //    // 将数据存储到缓存中，设置滑动过期时间为5分钟
            //    var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
            //    await cache.SetStringAsync(cacheKey, serializedEntity, cacheEntryOptions);

            //    var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
            //    var server = _connection.GetServer(_connection.GetEndPoints().First());
            //    var keys = server.Keys(pattern: "*");
            //    var db = _connection.GetDatabase();

            //    foreach (var key in keys)
            //    {
            //        if (key.ToString().StartsWith("ztDataNet:All"+typeof(T).Name))
            //        {
            //            await db.KeyDeleteAsync(key);
            //        }
            //    }

            //}

            return Ok(id);
        }
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        [HttpPost("AddRange")]
        public async Task<IActionResult> AddEntities([FromBody] List<T> entities)
        {
            var ids = new List<int>();

            try
            {
                db.Ado.BeginTran();

                foreach (var entity in entities)
                {
                    await db.Insertable(entity).ExecuteCommandAsync();
                    ids.Add(entity.id);

                    // 生成缓存键
                    var cacheKey = $"{typeof(T).Name}-{entity.id}";

                    // 将数据序列化为JSON
                    var serializedEntity = JsonConvert.SerializeObject(entity);

                    // 将数据存储到缓存中，设置滑动过期时间为5分钟
                    var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
                    await cache.SetStringAsync(cacheKey, serializedEntity, cacheEntryOptions);

                }
                var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
                var server = _connection.GetServer(_connection.GetEndPoints().First());
                var keys = server.Keys(pattern: "*");
                var db2 = _connection.GetDatabase();

                foreach (var key in keys)
                {
                    if (key.ToString().StartsWith("ztDataNet:All"+typeof(T).Name))
                    {
                        await db2.KeyDeleteAsync(key);
                    }
                }
                db.Ado.CommitTran();
            }
            catch (Exception)
            {
                db.Ado.RollbackTran();
                return BadRequest("An error occurred while adding entities");
            }

            return Ok(ids);
        }
        /// <summary>
        /// 根据id删除单条
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // DELETE: api/Entity/Delete/{id}
        [HttpDelete("Delete/{id}")]
        public async Task<IActionResult> DeleteEntity(string id)
        {
            var result = await db.Deleteable<T>().In(id).ExecuteCommandAsync();

            //if (result > 0)
            //{
            //    // 生成缓存键
            //    var cacheKey = $"{typeof(T).Name}-{id}";

            //    // 从缓存中移除数据
            //    await cache.RemoveAsync(cacheKey);
            //}
            //var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
            //var server = _connection.GetServer(_connection.GetEndPoints().First());
            //var keys = server.Keys(pattern: "*");
            //var db2 = _connection.GetDatabase();

            //foreach (var key in keys)
            //{
            //    if (key.ToString().StartsWith("ztDataNet:All"+typeof(T).Name))
            //    {
            //        await db2.KeyDeleteAsync(key);
            //    }
            //}
            return Ok(result);
        }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpDelete("DeleteRange")]
        public async Task<IActionResult> DeleteEntities([FromBody] List<string> ids)
        {
            var result = await db.Deleteable<T>().In(ids).ExecuteCommandAsync();

            foreach (var id in ids)
            {
                // 生成缓存键
                var cacheKey = $"{typeof(T).Name}-{id}";

                // 从缓存中移除数据
                await cache.RemoveAsync(cacheKey);

               
            }
            var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
            var server = _connection.GetServer(_connection.GetEndPoints().First());
            var keys = server.Keys(pattern: "*");
            var db2 = _connection.GetDatabase();

            foreach (var key in keys)
            {
                if (key.ToString().StartsWith("ztDataNet:All"+typeof(T).Name))
                {
                    await db2.KeyDeleteAsync(key);
                }
            }
            return Ok(result);
        }
        /// <summary>
        /// 更新单条
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        // PUT: api/Entity/Update
        [HttpPut("Update")]
        public async Task<IActionResult> UpdateEntity([FromBody] T entity)
        {
            var isUpdated = await db.Updateable(entity).ExecuteCommandAsync() > 0;

            //if (isUpdated)
            //{
            //    var cacheKey = $"{typeof(T).Name}-{entity.id}";

            //    // 将数据序列化为JSON
            //    var serializedEntity = JsonConvert.SerializeObject(entity);

            //    // 将数据存储到缓存中，设置滑动过期时间为5分钟
            //    var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
            //    await cache.SetStringAsync(cacheKey, serializedEntity, cacheEntryOptions);

            //    var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
            //    var server = _connection.GetServer(_connection.GetEndPoints().First());
            //    var keys = server.Keys(pattern: "*");
            //    var db = _connection.GetDatabase();

            //    foreach (var key in keys)
            //    {
            //        if (key.ToString().StartsWith("ztDataNet:All"+typeof(T).Name))
            //        {
            //            await db.KeyDeleteAsync(key);
            //        }
            //    }
            //}

            return Ok(isUpdated);
        }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        [HttpPut("UpdateRange")]
        public async Task<IActionResult> UpdateEntities([FromBody] List<T> entities)
        {
            var isUpdated = await db.Updateable(entities).ExecuteCommandAsync() > 0;

            //if (isUpdated)
            //{
            //    foreach (var entity in entities)
            //    {
            //        // 生成缓存键
            //        var cacheKey = $"{typeof(T).Name}-{entity.id}";

            //        // 将数据序列化为JSON
            //        var serializedEntity = JsonConvert.SerializeObject(entity);

            //        // 将数据存储到缓存中，设置滑动过期时间为5分钟
            //        var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
            //        await cache.SetStringAsync(cacheKey, serializedEntity, cacheEntryOptions);
            //    }
            //}
            //var _connection = await ConnectionMultiplexer.ConnectAsync(RedisConnection);
            //var server = _connection.GetServer(_connection.GetEndPoints().First());
            //var keys = server.Keys(pattern: "*");
            //var db2 = _connection.GetDatabase();

            //foreach (var key in keys)
            //{
            //    if (key.ToString().StartsWith("All"+typeof(T).Name))
            //    {
            //        await db2.KeyDeleteAsync(key);
            //    }
            //}
            return Ok(isUpdated);
        }
        /// <summary>
        /// 查询全部
        /// </summary>
        /// <returns></returns>
        // GET: api/Entity/GetAll
        [HttpGet("GetAll")]
        //public async Task<IActionResult> GetAllEntities()
        //{
        //    var result = await db.Queryable<T>().OrderBy(t => t.inputtime, OrderByType.Desc).ToListAsync();

        //    var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
        //    memoryCache.Set($"All{typeof(T).Name}", result, cacheEntryOptions);

        //    return Ok(result);

        //}
        public async Task<IActionResult> GetAllEntities()
        {
            var cacheKey = $"All{typeof(T).Name}-AllEntities";
            var cachedResults = await cache.GetStringAsync(cacheKey);

            if (cachedResults == null)
            {
                var results = await db.Queryable<T>().OrderBy(t => t.inputtime, OrderByType.Desc).ToListAsync();
                cachedResults = JsonConvert.SerializeObject(results);

                var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
                await cache.SetStringAsync(cacheKey, cachedResults, cacheEntryOptions);
            }

            return Ok(JsonConvert.DeserializeObject<List<T>>(cachedResults));
        }
        /// <summary>
        /// 根据id查询单条
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        // GET: api/Entity/Get/{id}
        [HttpGet("Get/{id}")]
        public async Task<IActionResult> GetEntityById(string id)
        {
            //// 尝试从缓存中获取数据
            //var cacheKey = $"{typeof(T).Name}-{id}";
            //var cachedResult = await cache.GetStringAsync(cacheKey);

            //if (cachedResult != null)
            //{
            //    // 如果缓存中有数据，将其反序列化并返回
            //    var result = JsonConvert.DeserializeObject<T>(cachedResult);
            //    return Ok(result);
            //}
            //else
            //{
                // 如果缓存中没有数据，从数据库中获取数据
                var result = await db.Queryable<T>().In(id).SingleAsync();

                //// 将数据序列化为JSON
                //var serializedResult = JsonConvert.SerializeObject(result);

                //// 将数据存储到缓存中，设置滑动过期时间为5分钟
                //var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
                //await cache.SetStringAsync(cacheKey, serializedResult, cacheEntryOptions);

                return Ok(result);
            //}
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("GetPaged/{pageNumber}/{pageSize}")]
        public async Task<IActionResult> GetPagedEntities(int pageNumber, int pageSize)
        {
            // 定义缓存键
            var cacheKey = $"All{typeof(T).Name}-Paged-{pageNumber}-{pageSize}";

            // 尝试从缓存中获取数据
            var cachedResult = await cache.GetStringAsync(cacheKey);

            if (cachedResult != null)
            {
                // 如果缓存中有数据，将其反序列化并返回
                var result = JsonConvert.DeserializeObject<List<T>>(cachedResult);
                return Ok(result);
            }
            else
            {
                // 如果缓存中没有数据，从数据库中获取数据
                var result = await db.Queryable<T>()
                                     .OrderBy(t => t.inputtime, OrderByType.Desc)
                                     .ToPageListAsync(pageNumber, pageSize);

                // 将数据序列化为JSON
                var serializedResult = JsonConvert.SerializeObject(result);

                // 将数据存储到缓存中，设置滑动过期时间为5分钟
                var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
                await cache.SetStringAsync(cacheKey, serializedResult, cacheEntryOptions);
              
                return Ok(result);
            }
        }

        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        /// 
        //[
        // {"FieldName":"dl","ConditionalType":"0","FieldValue":"道,剑,兵"},
        // {"FieldName":"fz","ConditionalType":"0","FieldValue":"炼药"}
        //]


        [HttpPost("GetByCondition")]
        public async Task<IActionResult> GetEntitiesByCondition([FromBody] string json)
        {
            var cacheKey = $"All{typeof(T).Name}-Condition-{json}";

            // 尝试从缓存中获取数据
            var cachedResult = await cache.GetStringAsync(cacheKey);

            if (cachedResult != null)
            {
                // 如果缓存中有数据，将其反序列化并返回
                var result = JsonConvert.DeserializeObject<List<T>>(cachedResult);
                return Ok(result);
            }
            else
            {
                var conModels = db.Utilities.JsonToConditionalModels(json);
            var result = await db.Queryable<T>().Where(conModels).ToListAsync();

                // 将数据序列化为JSON
                var serializedResult = JsonConvert.SerializeObject(result);

                // 将数据存储到缓存中，设置滑动过期时间为5分钟
                var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
                await cache.SetStringAsync(cacheKey, serializedResult, cacheEntryOptions);

                return Ok(result);
            }
        }

        /// <summary>
        /// 按时间段查询
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        [HttpGet("GetByTimeRange")]
        public async Task<IActionResult> GetByTimeRange(DateTime startTime, DateTime endTime)
        {
            // 定义缓存键
            var cacheKey = $"All{typeof(T).Name}-TimeRange-{startTime}-{endTime}";

            // 尝试从缓存中获取数据
            var cachedResult = await cache.GetStringAsync(cacheKey);

            if (cachedResult != null)
            {
                // 如果缓存中有数据，将其反序列化并返回
                var result = JsonConvert.DeserializeObject<List<T>>(cachedResult);
                return Ok(result);
            }
            else
            {
                var result = await db.Queryable<T>()
                                     .Where(e => e.inputtime >= startTime && e.inputtime <= endTime)
                                     .ToListAsync();

                // 将数据序列化为JSON
                var serializedResult = JsonConvert.SerializeObject(result);

                // 将数据存储到缓存中，设置滑动过期时间为5分钟
                var cacheEntryOptions = new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(5));
                await cache.SetStringAsync(cacheKey, serializedResult, cacheEntryOptions);

                return Ok(result);
            }
        }


       



    }

    /// <summary>
    /// 实体接口
    /// </summary>
    public interface IEntity
    {
        /// <summary>
        /// id
        /// </summary>
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
        int id { get; set; }

        /// <summary>
        /// 时间
        /// </summary>
        public System.DateTime? inputtime { get; set; }
    }

   
}
